package com.rc.saas.tenant.shiro;

import com.rc.saas.tenant.model.platform.PlatformUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by sven on 2018-08-31
 */
public class ShiroAuthorizationHelper {
    private static Logger logger = LoggerFactory.getLogger(ShiroAuthorizationHelper.class);

    //shiro 配置的cacheManager， 需要使用Spring bean进行注入
    private static CacheManager cacheManager;

    /**
     * 清除当前用户的权限
     */
    public static void clearAuthorizationInfo() {
        if (SecurityUtils.getSubject().isAuthenticated()) {
            Subject subject = SecurityUtils.getSubject();

            PlatformUser shiroUser = (PlatformUser) subject.getPrincipal();

            //String username = subject.getPrincipal().toString();
            String realmName = subject.getPrincipals().getRealmNames().iterator().next();

            String username = shiroUser.getLoginName();
            //String realmName = shiroUser.getn

            //SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(username, realmName);

            // 调用清理用户权限
            //clearAuthorizationInfo(principalCollection);

            //myShiroCache是我配置用于缓存的cache的Name，在spring配置文件中配置，可以看文章最后
            Cache<Object, Object> cache = cacheManager.getCache("cacheManager2");

            for (Object k : cache.keys()) {
                logger.info(k.getClass().toString());
            }
            cache.clear();
            //cache.remove(shiroUser);
        }
    }

    /**
     * 清除用户的权限
     * 这里需要注意的是，
     * 网上很多实现都是这里只传递一个String类型的username过来，根据这个String当key去清除Cache
     * 但是Shiro在缓存用户权限的时候使用的key并不是String类型，所以调用remove的时候并不能清除缓存的权限
     * shiro缓存时使用的key，是登录时使用的SimplePrincipalCollection对象，所以remove的时候需要的不是一个String值，
     * 具体可以参考下面方法中打印cache的key的过程, 可以看到打印出key的类是 `class org.apache.shiro.subject.SimplePrincipalCollection`
     * 所以你cache.remove(String username)肯定清除不了
     *
     * @param principal
     */
    public static void clearAuthorizationInfo(SimplePrincipalCollection principal) {
        logger.info("clear the user: " + principal.toString() + "'s authorizationInfo");

        //myShiroCache是我配置用于缓存的cache的Name，在spring配置文件中配置，可以看文章最后
        Cache<Object, Object> cache = cacheManager.getCache("cacheManager2");

        for (Object k : cache.keys()) {
            logger.info(k.getClass().toString());
        }

        cache.remove(principal);
    }

    /**
     * 由Spring bean将对象注入
     *
     * @param cacheManager
     */
    public static void setCacheManager(CacheManager cacheManager) {
        ShiroAuthorizationHelper.cacheManager = cacheManager;
    }

}
